////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//                                                                                                                            //
//                                                         WNProject                                                          //
//                                                                                                                            //
//            This file is distributed under the BSD 2-Clause open source license. See License.txt for details.               //
//                                                                                                                            //
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef __WN_MACROS_H__
#define __WN_MACROS_H__

#include "WNCore/inc/WNBase.h"
#include "WNCore/inc/WNDefines.h"

#ifdef _WN_LINUX
    #include <signal.h>
#endif

#include <stdio.h>

#define WN_BYTES_TO_BITS(_value) (WN_BITS_PER_BYTE * (_value))
#define WN_KILOBYTES_TO_BYTES(_value) (1024 * (_value))
#define WN_MEGABYTES_TO_BYTES(_value) (1024 * WN_KILOBYTES_TO_BYTES(_value))
#define WN_GIGABYTES_TO_BYTES(_value) (1024 * WN_MEGABYTES_TO_BYTES(_value))

#define WN_ARRAY_LENGTH(_array) (sizeof(_array) / sizeof(_array[0]))

#define WN_STRINGERIZE(_value) #_value

#ifdef _WN_MSVC
    #define WN_UNUSED_ARG(_argument) (_argument);
#else
    #define WN_UNUSED_ARG(_argument) ((WN_VOID)(sizeof((_argument), 0)))
#endif

#ifdef _WN_MSVC
    #define WN_IS_ADDRESS_ALIGNED(_ptr, _a) (__alignof(_ptr) == (_a))
#else
    #define WN_IS_ADDRESS_ALIGNED(_ptr, _a) (((WN_SIZE_T)((const WN_VOID*)(_ptr))) % (_a) == 0)
#endif

#ifdef _WN_DEBUG
    #ifdef _WN_LINUX
        #define _WN_DEBUG_BREAK() raise(SIGTRAP);
    #else
        #ifdef _WN_MSVC
            #define _WN_DEBUG_BREAK() __debugbreak();
        #elif defined _WN_GNUC
            #ifdef _WN_X86
                _WN_DEBUG_BREAK() __asm__ __volatile__ ("int $3");
            #elif defined _WN_PPC
                _WN_DEBUG_BREAK() __asm__ __volatile__ ("trap");
            #else
                _WN_DEBUG_BREAK()
            #endif
        #endif
    #endif
#else
    #define _WN_DEBUG_BREAK()
#endif

#ifdef _WN_MSVC
    #define WN_SNPRINTF _snprintf
#else
    #define WN_SNPRINTF snprintf
#endif

#define WN_PRINTF printf
#define WN_SPRINTF sprintf
#define WN_WSPRINTF wsprintf

#define WN_BIT_MASK(_bit) (1 << (_bit))
#define WN_BIT_SET(_value, _bit) ((_value) |= WN_BIT_MASK(_bit))
#define WN_BIT_CLEAR(_value, _bit) ((_value) &= ~WN_BIT_MASK(_bit))
#define WN_BIT_FLIP(_value, _bit) ((_value) ^= WN_BIT_MASK(_bit))
#define WN_BIT_TEST(_value, _bit) (((_value) & WN_BIT_MASK(_bit)) != 0)

#define WN_CHECK_FAIL(_arg) ((_arg) > 0)
#define WN_CHECK_SUCCESS(_arg) ((_arg) == 0)

#endif // __WN_MACROS_H__